import turtle
import time

def parse_gcode(file_path):
    """
    解析 G-code 文件并返回路径列表。
    每个路径是一个包含 (x, y, is_cut) 的列表，is_cut 标志是否为切割路径。
    """
    paths = []  # 存储路径
    current_path = []  # 当前路径

    with open(file_path, 'r') as file:
        for line in file:
            line = line.strip()
            if line.startswith(';') or not line:
                continue

            if line.startswith('G0') or line.startswith('G1'):
                x = y = None
                is_cut = line.startswith('G1')  # G1 表示切割路径
                tokens = line.split()
                for token in tokens:
                    if token.startswith('X'):
                        x = float(token[1:])
                    elif token.startswith('Y'):
                        y = float(token[1:])

                if x is not None and y is not None:
                    current_path.append((x, y, is_cut))

                # 如果是 G0 且当前路径非空，保存路径
                if line.startswith('G0') and current_path:
                    paths.append(current_path)
                    current_path = []

    # 保存最后一条路径
    if current_path:
        paths.append(current_path)

    return paths

def draw_dashed_line(pen, start, end, dash_length=10, scale=2, offset_x=-200, offset_y=-200):
    """
    绘制虚线，从 start 到 end。
    """
    x1, y1 = start
    x2, y2 = end

    # 将坐标按比例和偏移转换
    x1, y1 = x1 * scale + offset_x, y1 * scale + offset_y
    x2, y2 = x2 * scale + offset_x, y2 * scale + offset_y

    # 计算直线的方向向量和总长度
    dx = x2 - x1
    dy = y2 - y1
    total_length = (dx**2 + dy**2) ** 0.5

    # 单位向量
    unit_dx = dx / total_length
    unit_dy = dy / total_length

    # 当前绘制的起点
    current_length = 0
    while current_length < total_length:
        # 起点
        start_x = x1 + unit_dx * current_length
        start_y = y1 + unit_dy * current_length

        # 终点
        end_length = min(current_length + dash_length, total_length)
        end_x = x1 + unit_dx * end_length
        end_y = y1 + unit_dy * end_length

        # 绘制虚线段
        pen.penup()
        pen.goto(start_x, start_y)
        pen.pendown()
        pen.goto(end_x, end_y)

        # 跳过虚线间隔
        current_length = end_length + dash_length

def visualize_gcode(paths):
    """
    使用 turtle 动态可视化 G-code 路径。
    激光头逐步移动并动态绘制路径。
    """
    screen = turtle.Screen()
    screen.title("Dynamic G-code Visualization")
    screen.setup(width=800, height=800)
    screen.tracer(0)

    pen = turtle.Turtle()
    pen.speed(0)
    pen.pensize(2)
    pen.hideturtle()

    # 激光头的形状
    laser = turtle.Turtle()
    laser.shape("circle")
    laser.color("red")
    laser.penup()

    # 缩放比例和偏移量
    scale = 2
    offset_x, offset_y = -200, -200

    for path in paths:
        for i, (x, y, is_cut) in enumerate(path):
            # 转换坐标
            x_turtle = x * scale + offset_x
            y_turtle = y * scale + offset_y

            # 激光头移动
            laser.goto(x_turtle, y_turtle)

            if i > 0:
                # 处理上一点和当前点
                prev_x, prev_y, prev_cut = path[i - 1]
                if not is_cut:
                    # 空程路径：绘制虚线
                    draw_dashed_line(
                        pen,
                        (prev_x, prev_y),
                        (x, y),
                        dash_length=10,
                        scale=scale,
                        offset_x=offset_x,
                        offset_y=offset_y,
                    )
                else:
                    # 切割路径：绘制实线
                    pen.penup()
                    pen.goto(prev_x * scale + offset_x, prev_y * scale + offset_y)
                    pen.pendown()
                    pen.goto(x_turtle, y_turtle)

            screen.update()
            time.sleep(0.05)  # 控制绘制速度

    screen.mainloop()

if __name__ == "__main__":
    import sys
    import os
    # 获取当前文件所在目录并添加到环境路径
    current_dir = os.path.dirname(os.path.abspath(__file__))
    sys.path.append(current_dir)

    # 主程序
    gcode_file = os.path.join(current_dir, "output2.gcode")  # 动态拼接路径
    paths = parse_gcode(gcode_file)
    visualize_gcode(paths)
